package function.stream;

import java.util.Random;
import java.util.stream.Stream;

/**
 * 流运行机制，基本特性
 *
 * @author 旭旭
 * @create 2018-08-19 22:51
 **/
public class FeatureStream {
    public static void main(String[] args){
//        feature123();
        feature46();
//        feature5();
    }

    /**
     * 特性一 所有操作都是链式调用一个操作只迭代一次
     * 特性二 每一个中间流返回一个新的流，里面的sourceStage都指向同一个地方就是Head
     * 特性三 Head -> NextStage -> NextStage -> null
     */
    public static void feature123(){
        Random random = new Random();
        Stream<Integer> integerStream = Stream.generate(random::nextInt)
                .limit(500)
                .peek(x -> System.out.println("peek -> " + x))
                .filter(x -> {System.out.println("filter -> " + x);return x > 100000;});
        integerStream.count();
    }

    /**
     * 特性四 有状态操作（多个参数操作），会把无状态操作阶段分隔，单独处理。
     * parallel /  sequetial 这个2个操作也是中间操作，但是他们不创建新的流，而是修改
     * Head的并行状态，所以多次调用时只会生效最后一个。
     */
    public static void feature46(){
        Random random = new Random();
        Stream<Integer> integerStream = Stream.generate(random::nextInt)
                .limit(500)
                .peek(x -> System.out.println("peek -> " + x))
                .filter(x -> {System.out.println("filter -> " + x);return x > 100000;})
                .sorted((x,y) -> {System.out.println("sorted -> " + x);return x - y;})
                .filter(x -> {System.out.println("filter -> " + x);return x > 100000;})
//                .parallel()
                ;
        integerStream.count();
    }


    /**
     * 特性五 有状态操作并行环境下不一定能并行操作
     */
    public static void feature5(){
        Random random = new Random();
        Stream<Integer> integerStream = Stream.generate(random::nextInt)
                .limit(500)
                .peek(x -> print("peek -> " + x))
                .filter(x -> {print("filter -> " + x);return x > 100000;})
                .sorted((x,y) -> {print("sorted -> " + x);return x - y;})
                .filter(x -> {print("filter -> " + x);return x > 100000;})
                .parallel();
        integerStream.count();
    }

    private static void print(String x){
        System.out.println(Thread.currentThread().getName() + " " + x);
    }
}
